/*
 * Copyright 2007-2009 Perttu "celeron55" Ahola <celeron55@gmail.com>
 *
 * This file is part of jukumagic.
 *
 * jukumagic is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * jukumagic is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with jukumagic.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "common.h"
#include "pin.h"
#include "jukuapp.h"
#include "footprint.h"
#include "component.h"

Pin::Pin()
{
	//m_num = 0;
	m_type = PIN_THROUGH_HOLE;
	m_x = 0;
	m_y = 0;
	m_mark = 0;
}

Pin::Pin(Pin &pin)
{
	m_num = pin.m_num;
	m_name = pin.m_name;
	m_type = pin.m_type;
	m_x = pin.m_x;
	m_y = pin.m_y;
	m_mark = pin.m_mark;
}

Pin::~Pin()
{
}

JukuObject* Pin::MakeACopy()
{
	Pin *pin = new Pin(*this);
	return pin;
}

void Pin::WriteXML(TiXmlNode* root)
{
    TiXmlElement *element = new TiXmlElement("Pin");
    root->LinkEndChild(element);
	element->SetAttribute("num", m_num.mb_str(wxConvUTF8));
    element->SetAttribute("name", m_name.mb_str(wxConvUTF8));
    if(m_type == PIN_THROUGH_HOLE)
    	element->SetAttribute("type", "through-hole");
	else if(m_type == PIN_THROUGH_HOLE_INVISIBLE)
    	element->SetAttribute("type", "through-hole-invisible");
	element->SetAttribute("x", m_x);
	element->SetAttribute("y", m_y);
	if(m_mark != 0) element->SetAttribute("mark", m_mark);
	WriteBaseXML(element);
}

JukuObject* Pin::ReadFromXMLElement(TiXmlElement* element)
{
    Pin *pin = new Pin();

	//element->Attribute("num", &pin->m_num);
	pin->m_num = wxString(element->Attribute("num"), wxCSConv(_T("ISO-8859-15")));

	pin->m_name = wxString(element->Attribute("name"), wxCSConv(_T("ISO-8859-15")));

	std::string type_s = element->Attribute("type");
	if(type_s == "through-hole") pin->m_type = PIN_THROUGH_HOLE;
	else if(type_s == "through-hole-invisible") pin->m_type = PIN_THROUGH_HOLE_INVISIBLE;
	
	element->Attribute("x", &pin->m_x);
	element->Attribute("y", &pin->m_y);

	element->Attribute("mark", &pin->m_mark);

	pin->ReadBaseXML(element);

    return pin;
}


void Pin::Draw(wxDC &dc, wxWindow *window, wxPoint origin)
{
	//std::cout<<"Pin::Draw()"<<std::endl;
	switch(m_type)
	{
	case PIN_THROUGH_HOLE:
		{
			int xadd = m_x + origin.x;
			int yadd = m_y + origin.y;
			if(GetSelected()){
				wxPen pen(wxGetApp().m_settings.m_colour_selected,
						wxGetApp().m_settings.m_linewidth_pin_through_hole);
				dc.SetPen(pen);
			}
			else{
				wxPen pen(wxGetApp().m_settings.m_colour_pin_through_hole,
						wxGetApp().m_settings.m_linewidth_pin_through_hole);
				dc.SetPen(pen);
			}
			wxBrush brush(*wxBLACK, wxTRANSPARENT);
			dc.SetBrush(brush);
			wxPoint points[3];
			points[0] = wxPoint(-15+xadd, -10+yadd);
			points[1] = wxPoint(15+xadd, -10+yadd);
			points[2] = wxPoint(0+xadd, 15+yadd);
			dc.DrawPolygon(3, points);
			if(m_mark == 1){
				dc.DrawRectangle(-27+xadd, -27+yadd, 60, 60);
			}
			if(wxGetApp().m_settings.m_show_pin_info){
				dc.SetTextForeground(wxGetApp().m_settings.m_colour_pin_textfg);
				dc.SetFont(wxGetApp().m_settings.m_font_pin_text);
				wxString s;
				wxString *t = &s;
				if(wxGetApp().m_settings.m_show_pin_info == 1){
					t = &m_name;
				}
				else if(wxGetApp().m_settings.m_show_pin_info == 2){
					//s << m_num;
					//t = &s;
					t = &m_num;
				}
				int w, h;
				dc.GetTextExtent(*t, &w, &h);
				dc.SetPen(wxPen(wxGetApp().m_settings.m_colour_pin_textbg, 0));
				dc.SetBrush(wxBrush(wxGetApp().m_settings.m_colour_pin_textbg));
				dc.DrawRectangle(-w/2+xadd, -h/2+yadd, w, h);
				dc.DrawText(*t, -w/2 + xadd, -h/2 + yadd);
			}
		}
		break;
	case PIN_THROUGH_HOLE_INVISIBLE:
		break;
	}
}

BoardRect Pin::GetDrawArea()
{
	switch(m_type)
	{
	case PIN_THROUGH_HOLE:
		//return BoardRect(-50+m_x, -50+m_y, 100, 100);
		return BoardRect(-wxGetApp().m_settings.m_width_pin_max/2 + m_x, -50 + m_y,
				wxGetApp().m_settings.m_width_pin_max, 100);
	case PIN_THROUGH_HOLE_INVISIBLE:
		return BoardRect(m_x,m_y,0,0);
	}
	return BoardRect(0,0,0,0);
}

void Pin::Move(int dx, int dy)
{
	m_x += dx;
	m_y += dy;
}

void Pin::Rotate(TurnDirection dir, BoardPoint origin)
{
	int ox = m_x - origin.m_x;
	int oy = m_y - origin.m_y;
	int nox, noy;
	if(dir==CCW){
		nox = oy;
		noy = -ox;
	}
	else{ //CW
		nox = -oy;
		noy = ox;
	}
	m_x = origin.m_x + nox;
	m_y = origin.m_y + noy;
}

//

Component* Pin::GetComponent()
{
	if(!m_owner) return NULL;
	if(!m_owner->m_owner) return NULL;
	if(m_owner->m_owner->GetType() != TYPE_FOOTPRINT) return NULL;
	Footprint *f = (Footprint*)(m_owner->m_owner);
	if(!f) return NULL;
	if(!f->m_owner) return NULL;
	if(f->m_owner->GetType() != TYPE_COMPONENT) return NULL;
	return (Component*)f->m_owner;
}

BoardPoint Pin::GetComponentPinPosition()
{
	Component *c = GetComponent();
	if(!c) return BoardPoint();
	int x = c->GetBoardPos().m_x + m_x;
	int y = c->GetBoardPos().m_y + m_y;
	return BoardPoint(x, y);
}




